package me.ywy.opengltest.utils;

import android.content.Context;
import android.opengl.GLES20;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class OpenGLUtils {

    public static String readRawTextFile(Context context, int rawId) {
        InputStream is = context.getResources().openRawResource(rawId);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuilder sb = new StringBuilder();
        try {
            while ((line = br.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static int loadProgram(String vSource, String fSource) {

        //顶点着色器
        int vShaderId = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(vShaderId , vSource);
        GLES20.glCompileShader(vShaderId);
        //查看配置是否成功
        int[] status = new int[1];
        GLES20.glGetShaderiv(vShaderId , GLES20.GL_COMPILE_STATUS ,status , 0);
        if(status[0] != GLES20.GL_TRUE){
            throw  new IllegalStateException("顶点着色器配置失败");
        }


        //片元着色器
        int fShaderId = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fShaderId , fSource);
        GLES20.glCompileShader(fShaderId);
        //查看配置 是否成功
        GLES20.glGetShaderiv(fShaderId , GLES20.GL_COMPILE_STATUS ,status , 0);
        if(status[0] != GLES20.GL_TRUE){
            throw  new IllegalStateException("片元着色器配置失败");
        }


        //创建着色器程序
        int program = GLES20.glCreateProgram();
        GLES20.glAttachShader(program,vShaderId);
        GLES20.glAttachShader(program,fShaderId);
        //链接着色器程序
        GLES20.glLinkProgram(program);
        //获得状态
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS , status , 0);
        if(status[0] != GLES20.GL_TRUE){
            throw  new IllegalStateException("着色器链接失败");
        }
        //因为已经绑定 所以可以删除
        GLES20.glDeleteShader(fShaderId);
        GLES20.glDeleteShader(vShaderId);

        return program;

    }

    public static void glGenTextures(int[] textures) {
//创建
        GLES20.glGenTextures(textures.length, textures, 0);
        //配置
        for (int i = 0; i < textures.length; i++) {
            // opengl的操作 面向过程的操作
            //bind 就是绑定 ，表示后续的操作就是在这一个 纹理上进行
            // 后面的代码配置纹理，就是配置bind的这个纹理
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textures[i]);
            /**
             * 过滤参数
             *  当纹理被使用到一个比他大 或者比他小的形状上的时候 该如何处理
             */
            // 放大
            // GLES20.GL_LINEAR  : 使用纹理中坐标附近的若干个颜色，通过平均算法 进行放大
            // GLES20.GL_NEAREST : 使用纹理坐标最接近的一个颜色作为放大的要绘制的颜色
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_NEAREST);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);

            /*设置纹理环绕方向*/
            //纹理坐标 一般用st表示，其实就是x y
            //纹理坐标的范围是0-1。超出这一范围的坐标将被OpenGL根据GL_TEXTURE_WRAP参数的值进行处理
            //GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T 分别为x，y方向。
            //GL_REPEAT:平铺
            //GL_MIRRORED_REPEAT: 纹理坐标是奇数时使用镜像平铺
            //GL_CLAMP_TO_EDGE: 坐标超出部分被截取成0、1，边缘拉伸
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);

            //解绑
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
        }
    }
}
